package main

import (
	"encoding/base64"
	"flag"
	"fmt"
	"net/url"
	"runtime"
	"sync"
	"sync/atomic"
	"time"
	"yan-feeorder/common"
	log "ycx-glog"
)

const KEY string = "QOSGCYQDPIWAJZFD"                    //key值
const ACCOUNT string = "IMTC300012"                      //账号
const PASSWORD string = "123456"                         //密码
const BASEURL string = "http://127.0.0.1:8888/api/ver20" //基础地址
const FEEDOINGURL string = "/fee/doing"                  //办理地址
const USERINFOURL string = "/account/info"               //账户信息地址
const FEEDATALIST string = "/fee/datalist"               //获取套餐地址

func doRequest(data string, thd_id int, wg *sync.WaitGroup, cond *common.Cond, errCount *int64, maxRunTimes *int64) {
	defer wg.Done()

	for {
		currentTimes := atomic.LoadInt64(maxRunTimes)
		if currentTimes <= 0 {
			break
		}

		cond.Wait()
		_, _, err := common.HttpSend(data, nil, nil, time.Duration(5*1e9))
		if err != nil {
			atomic.AddInt64(errCount, 1)
		}
		//log.Infof("线程[%02d]执行第%08d次\n", thd_id, currentTimes)
		cond.Signal()

		atomic.AddInt64(maxRunTimes, -1)
	}
}

func main() {

	/************ 加载日志模块 ************/

	// 日志目录
	logDir := common.EnsureDir("./_glog/" + log.LogDirName())
	if runtime.GOOS == "windows" {
		flag.Set("alsologtostderr", "true")
	} else {
		flag.Set("alsologtostderr", "false")
		// 记录严重错误(仅linux有效)
		common.RecordFatal(fmt.Sprintf("./_log/fatal_%s.log", common.TimeFormat(time.Now(), "yyyyMMdd_HHmmss")))
	}
	flag.Set("log_dir", logDir)
	flag.Set("v", "3")
	flag.Parse()
	//
	log.MaxSize = 1024 * 1024 * 10 //10M
	log.DirMaxSize = log.MaxSize * 30
	defer log.Flush()
	request := map[string]string{
		"req_plus": "160126550537646670",
		"price":    "20",
		"mobile":   "18841714609",
	}
	url := BASEURL + FEEDOINGURL
	str := makeFee(request)

	log.Infoln(url)
	log.Infoln(str)
	data := url + "?" + str

	log.Infoln("开始", time.Now())

	maxThread := 5
	maxRunTimes := int64(10000)
	errCount := int64(0)
	cond := common.NewCond(3)
	cond.Broadcast()

	wg := &sync.WaitGroup{}
	for thd_id := 0; thd_id <= maxThread; thd_id++ {
		wg.Add(1)
		go doRequest(data, thd_id, wg, cond, &errCount, &maxRunTimes)
	}
	wg.Wait()

	log.Infoln("结束", time.Now(), errCount)
}

/**
*话费办理功能
*****/
func makeFee(request map[string]string) string {

	Req := map[string]interface{}{
		"account":  ACCOUNT,
		"password": PASSWORD,
		"request":  request,
	}
	p := common.JsonEncode(Req)

	requestStr, _ := common.Encrypt([]byte(p), []byte(KEY))
	encodeString := base64.StdEncoding.EncodeToString(requestStr)
	Reqs := map[string]string{
		"user": ACCOUNT,
		"data": encodeString,
	}
	strr := httpBuildQueryEncode(Reqs)

	return strr

}

/**
* 功能:把键值对以"key值=键值"用&字符链接起来
* 参数:kvs为数组
 */
func httpBuildQueryEncode(kvs map[string]string) string {
	var prestr string
	var keys []string
	for k := range kvs {
		keys = append(keys, k)
	}
	ln := len(keys)
	for i := 0; i < ln; i++ {
		key := keys[i]
		value := kvs[key]

		if i == ln-1 { //拼接时，不包括最后一个&字符
			prestr = prestr + key + "=" + url.QueryEscape(value)
		} else {
			prestr = prestr + key + "=" + url.QueryEscape(value) + "&"
		}
	}

	return prestr
}

func httpBuildQuery(kvs map[string]string) string {
	var prestr string
	var keys []string
	for k := range kvs {
		keys = append(keys, k)
	}
	ln := len(keys)
	for i := 0; i < ln; i++ {
		key := keys[i]
		value := kvs[key]

		if i == ln-1 { //拼接时，不包括最后一个&字符
			prestr = prestr + key + "=" + value
		} else {
			prestr = prestr + key + "=" + value + "&"
		}
	}

	return prestr
}
